<?php

function C($key, $val = null) {
    static $config = [];

    if (is_array($key)) {
        $config = array_merge($config, $key);

        return true;
    }

    if (is_null($val)) {
        return $config[$key] ?? '';
    }

    $config[$key] = $val;

    return true;
}

/**
 * get_db_connect
 * 返回数据库连接
 */
function get_db_connect() {
    static $db = null;

    if ($db) {
        return $db;
    }

    $dsn = 'pgsql:host='. C('DB_HOST')
         . ';port='     . C('DB_PORT')
         . ';dbname='   . C('DB_NAME')
         . ';user='     . C('DB_USER')
         . ';password=' . C('DB_PWD');

    return $db = new PDO($dsn);
}


/**
 * get_full_url
 * 返回包含http协议的完整网址，如果网址中
 * 已经有http://或https://，则不做任何处理，
 * 如果不存在上述两种中任何一种，则默认加上http://
 *
 * @param mixed $url
 * @access public
 * @return void
 */
function get_full_url($url) {
    $prefix = strtolower(substr($url, 0, 7));

    if ($prefix == 'http://' || $prefix == 'https:/') {
        return $url;
    }

    return 'http://' . $url;
}


/**
 * check_domain_intercept
 * 检测域名是否被微信拦截
 * [0]正常     不拦截分享也可见
 * [1]白名单   不拦截但分享仅自己可见 别人看不到
 * [2]黑名单   被拦截
 * [3]查询失败
*/
function check_domain_intercept($domain){
    $apiUrl = 'http://api.quange.com.cn/weixin/42895383.php?domain=';
    $domain = str_replace(['http://', 'https://'], ['', ''], $domain);
    //$items  = explode('/', $domain);
    //$domain = array_shift($items);
    $url    = $apiUrl . $domain;

    $ch = curl_init();
    curl_setopt($ch,CURLOPT_TIMEOUT,5);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);

    $data = curl_exec($ch);
    $r    = '';

    if ($data){
        $r = json_decode($data, true);
    }

    curl_close($ch);

    return $r;
}

/**
 * change_plan_url
 * 替换广告计划网址
 *
 * $planId对应广告计划正在投放使用的所有设备的网址换成$newUrl
 * 并将opts.bak_urls中对$newUrl对应的网址打上禁用标记，
 * 然后生成广告计划缓存
 *
 * hold_bak_url()如果放在change_plan_url()内执行时会导致change_plan_url()保存数据时
 * 覆盖hold_bak_url()之前保存的数据
 *
 * @param mixed $planId     计划编号
 * @param mixed $toUrl      替换成的新网址
 */
function change_plan_url($planId, $newUrl) {
    $planId = (int)$planId;

    if (empty($planId)) {
        return false;
    }

    $db = get_db_connect();

    if (!$query = $db->query("SELECT * FROM public.plan WHERE id={$planId} LIMIT 1")) {
        return false;
    }

    if ((!$record = $query->fetch(PDO::FETCH_ASSOC)) || empty($record['opts'])) {
        return false;
    }

    if ((!$opts = json_decode($record['opts'], true)) || empty($opts['devices'])) {
        return false;
    }

    $newUrl = get_full_url($newUrl);

    /**
     * 替换计划正在使用的网址为$newUrl
     */
    foreach ($opts['devices'] as $k => $v) {
        $opts['devices'][$k]['url'] = $newUrl;
    }

    /**
     * 更新planId对应数据记录及缓存
     */
    $tmp = json_encode($opts);
    $db->exec("UPDATE plan SET opts='{$tmp}' WHERE id={$planId}");
    cacheApi('plan', [
        'a'  => 'modify',
        'id' => $planId,
    ]);
    
    return true;
}

/**
 * get_allow_bak_url
 * 从$planId对应的计划中返回一条可用备用网址
 * 成功返回可用网址，出错返回false
 *
 * @param mixed $bakUrls    备用网址数组
 * @access public
 * @return void
 */
function get_allow_bak_url($planId) {
    $planId = (int)$planId;

    if (empty($planId)) {
        return false;
    }

    $db = get_db_connect();

    if (!$query = $db->query("SELECT opts FROM public.plan WHERE id={$planId} LIMIT 1")) {
        return false;
    }

    if ((!$record = $query->fetch(PDO::FETCH_ASSOC)) || empty($record['opts'])) {
        return false;
    }

    if ((!$opts = json_decode($record['opts'], true)) || empty($opts['bak_urls'])) {
        return false;
    }

    foreach ($opts['bak_urls'] as $k => $v) {
        if ((!$tmp = parse_bak_url_record($v)) || empty($tmp['status'])) {
            continue;
        }

        return $tmp['url'];
    }

    return false;
}

/**
 * parse_bak_url_record
 * 分解备用网址中一条记录，返回分解后的结果
 * 成功返回数据集，出错返回false
 *
 * 数据集结构:
 * [
 *      'url' => '网址',
 *      'time' => '如果是禁用状态，则返回禁用时间，如果未禁用，返回字符串',
 *      'status' => '0表示禁用，1表示可用',
 * ]
 *
 * @param mixed $record
 * @access public
 * @return void
 */
function parse_bak_url_record($record) {
    $r = [];
    list($r['url'], $r['time'], $r['status']) = explode('|', $record . '||');
    $r['url'] = get_full_url(trim($r['url']));

    $r['status'] = $r['status'] == 'HOLD' ? 0 : 1;

    return $r;
}


/**
 * hold_bak_url
 * 禁用备用网址指定的$url
 *
 * @param mixed $planId 计划编号
 * @param mixed $url    待禁用网址
 * @access public
 * @return void
 */
function hold_bak_url($planId, $url, $status = 'HOLD', $msg = null) {
    $planId = (int)$planId;

    if (empty($planId)) {
        return false;
    }

    $db = get_db_connect();

    if (!$query = $db->query("SELECT opts FROM public.plan WHERE id = {$planId}")) {
        return false;
    }

    if ((!$record = $query->fetch(PDO::FETCH_ASSOC)) || empty($record['opts'])) {
        return false;
    }

    if ((!$opts = json_decode($record['opts'], true)) || empty($opts['bak_urls'])) {
        return false;
    }

    foreach ($opts['bak_urls'] as $k => $v) {
        $tmp = parse_bak_url_record($v);

        if ($tmp['url'] != $url) {
            continue;
        }

        $opts['bak_urls'][$k] = implode('|', [$url, date('Y-m-d H:i:s'), $status, $msg ?? null]);

        break;
    }

    $tmp = json_encode($opts);
    $db->exec("UPDATE public.plan SET opts = '{$tmp}' WHERE id={$planId}");

    return true;
}

/**
 * collect
 * 获取$url网页内容
 *
 * @param mixed $url
 * @access public
 * @return void
 */
function collect($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);   //不直接输出获取的数据
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);   //连接超时，3秒如果连接不成功，则超时
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 3000); //尝试重连超时时间，单位毫秒
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 执行超时(秒)，一定要加上此项，否则有时可能因$sUrl访问不成功导致进程阻塞
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:28.0) Gecko/20100101 Firefox/28.0');
    $r = curl_exec($ch);
    /*
     *$error = curl_errno($rCh);
     *var_dump($error);
     */
    curl_close($ch);

    return $r;
}

/**
 * check_weixin_mp_article_intercept
 * 检测公众号文章是否被拦截
 *
 * 返回逻辑值，true表示被封，false表示正常
 *
 * @param mixed $url
 * @access public
 * @return void
 */
function check_weixin_mp_article_intercept($url) {
    if (!$html = collect($url)) {
        return false;
    }

    $regx = ['#<div class="global_error_msg warn">\s+(该内容已被发布者删除)\s+</div>#',
             '#<p>(此内容因违规无法查看)</p>#'
            ];

    foreach ($regx as $k => $v) {
        preg_match($v, $html, $tmp);

        if (!empty($tmp)) {
            return true;
        }
    }

    return false;
}
